package com.cxb.utils;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;
import android.util.Log;
import com.cxb.entity.AccessPoint;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static android.content.Context.CONNECTIVITY_SERVICE;

/**
 * Author jerry
 * date: 2016/8/6.
 */
public class WifiUtils {
	private static final String TAG = "wifi_mode";
	private static Context sContext;
	private static WifiManager sWifiManager;
	public boolean isWifiApEnabled() {
		try {
			Method method = sWifiManager.getClass().getMethod(
					METHOD_IS_WIFI_AP_ENABLED);
			method.setAccessible(true);
			return (Boolean) method.invoke(sWifiManager);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private static final String METHOD_SET_WIFI_AP_ENABLE = "setWifiApEnabled";
	private static final String METHOD_IS_WIFI_AP_ENABLED = "isWifiApEnabled";
	private static final String METHOD_GET_WIFI_AP_STATE = "getWifiApState";

	private static Method sSetWifiApEnable;
	private static Method sIsWifiApEnable;
	private static Method sGetWifiStatus;


	public static void init(Context context){
		if(sContext == null){
			sContext = context;
			sWifiManager = (WifiManager) sContext.getSystemService(Context.WIFI_SERVICE);

			try {
				sSetWifiApEnable = sWifiManager.getClass().
						getDeclaredMethod(METHOD_SET_WIFI_AP_ENABLE, WifiConfiguration.class,boolean.class);
				sSetWifiApEnable.setAccessible(true);
				sIsWifiApEnable = sWifiManager.getClass().getDeclaredMethod(METHOD_IS_WIFI_AP_ENABLED);
				sIsWifiApEnable.setAccessible(true);
				sGetWifiStatus = sWifiManager.getClass().getDeclaredMethod(METHOD_GET_WIFI_AP_STATE);
				sGetWifiStatus.setAccessible(true);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	public enum WifiCipherType {
		WIFICIPHER_WEP, WIFICIPHER_WPA, WIFICIPHER_NOPASS, WIFICIPHER_INVALID,WIFICIPHER_UNKNOW
	}

	public static WifiCipherType getWifiCipher(String capabilities) {

		if(TextUtils.isEmpty(capabilities)){
			return WifiCipherType.WIFICIPHER_INVALID;
		}
		if (capabilities.contains("WEP")) {
			return WifiCipherType.WIFICIPHER_WEP;
		} else if (capabilities.contains("PSK")) {
			return WifiCipherType.WIFICIPHER_WPA;
		} else {
			return WifiCipherType.WIFICIPHER_NOPASS;
		}
	}

	/**
	 * 将扫描到的wifi列表结果集转换成"可访问点"实体，并按照信号强度排序
	 * @param scanResults
	 * @return
	 */
	public static List<AccessPoint> parseAccesspoint(List<ScanResult> scanResults){
		List<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
//		Log.e(TAG, "===============================================================");
		for(ScanResult result : scanResults){
			if (result.SSID == null || result.SSID.length() == 0 ||
				result.capabilities.contains("[IBSS]")) {
				continue;
			}

//			if(result.SSID.startsWith("ADAS_")){
//				continue;
//			}
			if(result.SSID.startsWith("iPhone") || result.SSID.startsWith("Net")){
				Log.e(TAG, "found:"+result.SSID);
			}
			//如果信号超级弱，也不要了
			if(WifiManager.calculateSignalLevel(result.level, 5) == 0){
				continue;
			}
			AccessPoint accessPoint = new AccessPoint(result);
			accessPoints.add(accessPoint);
//			Log.e(TAG, accessPoint.toString());
		}
//		Log.e(TAG, "===============================================================");
		if(accessPoints.size() != 0){
			Collections.sort(accessPoints);
		}
		return accessPoints;
	}


	public static boolean enableWifi(boolean enable){
		int wifiApState = 0;
		try {
			wifiApState = (Integer) sGetWifiStatus.invoke(sWifiManager);
			//WIFI_AP_STATE_ENABLING = 12 WIFI_AP_STATE_ENABLED = 13
			if (enable && ((wifiApState == 12) || (wifiApState == 13))) {
				sSetWifiApEnable.invoke(sWifiManager, null, false);
			}

			if(!sWifiManager.setWifiEnabled(enable)){
			//	Toast.makeText(sContext, "setWifiEnabled failed", Toast.LENGTH_LONG).show();
				return false;
			}else {
			//	Toast.makeText(sContext, "setWifiEnabled success", Toast.LENGTH_LONG).show();
			}

			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

	public static WifiConfiguration generateWifiConfiguration(AccessPoint accessPoint, String pwd){
		WifiConfiguration config = new WifiConfiguration();
		config.SSID = WifiUtils.convertToQuotedString(accessPoint.SSID);
		switch (accessPoint.cipherType) {
			case WIFICIPHER_NOPASS: {
				config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
				break;
			}

			case WIFICIPHER_WEP: {
				config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
				config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
				config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
				if (pwd.length() != 0) {
					int length = pwd.length();
					String password = pwd;
					// WEP-40, WEP-104, and 256-bit WEP (WEP-232?)
					if ((length == 10 || length == 26 || length == 58) &&
						password.matches("[0-9A-Fa-f]*")) {
						config.wepKeys[0] = password;
					} else {
						config.wepKeys[0] = '"' + password + '"';
					}
				}
				break;
			}

			case WIFICIPHER_WPA: {
				config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
				if (pwd.length() != 0) {
					String password = pwd;
					if (password.matches("[0-9A-Fa-f]{64}")) {
						config.preSharedKey = password;
					} else {
						config.preSharedKey = '"' + password + '"';
					}
				}
				break;
			}
			default: {
				throw new IllegalArgumentException("para accessPoint with invalid cipherType");
			}
		}

		return config;
	}

	public static String convertToQuotedString(String string) {
		return "\"" + string + "\"";
	}

	/**
	 * 查看之前是否配置过该SSID
	 * @param SSID
	 * @return
	 */
	public static WifiConfiguration isConfigExist(String SSID) { // 查看以前是否已经配置过该SSID
		List<WifiConfiguration> existingConfigs = sWifiManager
				.getConfiguredNetworks();
		String ssid = WifiUtils.convertToQuotedString(SSID);
		for (WifiConfiguration existingConfig : existingConfigs) {
			if (existingConfig.SSID.equals(ssid) ){
				return existingConfig;
			}
		}
		return null;
	}

	public static boolean connectWifi(AccessPoint accessPoint){
		String pwd = accessPoint.pwd;
		WifiConfiguration config = WifiUtils.isConfigExist(accessPoint.SSID);
		if(config != null){
			sWifiManager.removeNetwork(config.networkId);
		}
		config = WifiUtils.generateWifiConfiguration(accessPoint, pwd);
		int netWorkID = sWifiManager.addNetwork(config);
		boolean result = sWifiManager.enableNetwork(netWorkID, true);
		return result;
	}

	public static WifiInfo getCurrentWifiInfo(Context context){
		ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
		if(connectivityManager != null ){
			NetworkInfo wifiInfo = connectivityManager.getActiveNetworkInfo();
			if(wifiInfo != null && wifiInfo.getType() == ConnectivityManager.TYPE_WIFI){
			//	Toast.makeText(context,"有wifi", Toast.LENGTH_SHORT).show();
				return sWifiManager.getConnectionInfo();
			}
		}
		return null;
	}

	public static WifiCipherType getCipherTypeBySSID(String ssid){
		WifiConfiguration configuration = WifiUtils.isConfigExist(ssid);
		WifiCipherType type = WifiCipherType.WIFICIPHER_INVALID;
		if(configuration != null){
	//		Log.e(TAG, configuration.toString());
			if(!TextUtils.isEmpty(configuration.preSharedKey)){
				type = WifiUtils.WifiCipherType.WIFICIPHER_WPA;
			}else if(!TextUtils.isEmpty(configuration.wepKeys[0])){
				type = WifiUtils.WifiCipherType.WIFICIPHER_WEP;
			}else {
				type = WifiCipherType.WIFICIPHER_NOPASS;
			}
		}else {
			//Toast.makeText(sContext, "configuration=null", Toast.LENGTH_SHORT).show();
		}
		return type;
	}

//	public static String getPwdBy(String ssid){
//		WifiConfiguration configuration = WifiUtils.isConfigExist(ssid);
//		String pwd;
//		if(configuration != null){
//			if(!TextUtils.isEmpty(configuration.preSharedKey)){
//				pwd = configuration.preSharedKey;
//			}else if(!TextUtils.isEmpty(configuration.wepKeys[0])){
//				pwd = configuration.wepKeys[0];
//			}else {
//				pwd = "";
//			}
//		}else {
//			pwd = "";
//		}
//		return pwd;
//	}
}
